<script setup lang="ts">
import { ref, watch, computed } from "vue";
import { ElMessage } from "element-plus";
import type { FormInstance, FormRules } from "element-plus";
import type { Menu } from "@/api/menu";
import { createMenu, updateMenu, getMenuList } from "@/api/menu";

const props = defineProps<{
  visible: boolean;
  menu?: Partial<Menu>;
  type: "add" | "edit";
}>();

const emit = defineEmits<{
  (e: "update:visible", value: boolean): void;
  (e: "save"): void;
}>();

const formRef = ref<FormInstance>();
const loading = ref(false);

// 菜单树数据
const menuTree = ref<Menu[]>([]);

// 计算当前是否为父级菜单
const isRootMenu = computed(() => formData.value.parentId === 0);

// 获取菜单树
const getMenuTree = async () => {
  try {
    const res = await getMenuList();
    if (res.code === 0) {
      menuTree.value = res.data;
    }
  } catch (error) {
    console.error("获取菜单树出错:", error);
  }
};

// 构建菜单树
const buildMenuTree = (menus: Menu[], parentId = 0): Menu[] => {
  return menus
    .filter(menu => menu.parentId === parentId)
    .map(menu => ({
      ...menu,
      children: buildMenuTree(menus, menu.id)
    }));
};

const formData = ref({
  name: "",
  parentId: 0,
  path: "",
  component: "",
  title: "",
  icon: "",
  rank: 0,
  status: 0,
  auths: []
});

// 表单验证规则
const formRules = ref<FormRules>({
  name: [
    { required: true, message: "请输入路由名称", trigger: "blur" },
    { min: 2, max: 50, message: "长度在 2 到 50 个字符", trigger: "blur" }
  ],
  path: [
    { required: true, message: "请输入路由路径", trigger: "blur" },
    { pattern: /^\/[a-zA-Z0-9\/-]*$/, message: "路由路径必须以/开头，只能包含字母、数字、斜杠和中划线", trigger: "blur" }
  ],
  component: [
    { required: true, message: "请输入组件路径", trigger: "blur" }
  ],
  title: [
    { required: true, message: "请输入菜单标题", trigger: "blur" },
    { min: 2, max: 50, message: "长度在 2 到 50 个字符", trigger: "blur" }
  ],
  rank: [
    { required: true, message: "请输入菜单排序", trigger: "blur" },
    { type: "number", message: "排序号必须为数字", trigger: "blur" }
  ]
});

// 监听visible变化，重置表单
watch(() => props.visible, (val) => {
  if (val) {
    formData.value = {
      name: props.menu?.name || "",
      parentId: props.menu?.parentId ?? 0,
      path: props.menu?.path || "",
      component: props.menu?.component || "",
      title: props.menu?.title || props.menu?.meta?.title || "",
      icon: props.menu?.icon || props.menu?.meta?.icon || "",
      rank: props.menu?.rank ?? props.menu?.meta?.rank ?? 0,
      status: props.menu?.status ?? 0,
      auths: props.menu?.auths || props.menu?.meta?.auths || []
    };
    // 获取菜单树
    getMenuTree();
  } else {
    formRef.value?.resetFields();
  }
});

// 监听parentId变化，自动设置组件
watch(() => formData.value.parentId, (newVal) => {
  if (newVal === 0) {
    // 父级菜单固定使用Layout组件
    formData.value.component = "Layout";
    // 父级菜单不需要按钮权限
    formData.value.auths = [];
  } else if (formData.value.component === "Layout") {
    // 如果从父级菜单变为子菜单，且组件还是Layout，则清空组件
    formData.value.component = "";
  }
});

// 提交表单
const handleSubmit = async () => {
  if (!formRef.value) return;

  // 根据菜单级别处理数据
  if (formData.value.parentId === 0) {
    formData.value.component = "Layout";
    formData.value.auths = [];
  }

  await formRef.value.validate(async (valid) => {
    if (valid) {
      loading.value = true;
      try {
        const api = props.type === "add" ? createMenu : updateMenu;
        const data = props.type === "add"
          ? formData.value
          : { ...formData.value, id: props.menu?.id };

        const res = await api(data);
        if (res.code === 0) {
          ElMessage.success(props.type === "add" ? "添加成功" : "编辑成功");
          emit("update:visible", false);
          emit("save");
        } else {
          ElMessage.error(res.msg || (props.type === "add" ? "添加失败" : "编辑失败"));
        }
      } catch (error) {
        console.error(props.type === "add" ? "添加菜单出错:" : "编辑菜单出错:", error);
        ElMessage.error(props.type === "add" ? "添加失败" : "编辑失败");
      } finally {
        loading.value = false;
      }
    }
  });
};

// 取消
const handleCancel = () => {
  emit("update:visible", false);
};
</script>

<template>
  <el-dialog :title="type === 'add' ? '添加菜单' : '编辑菜单'" :model-value="visible"
    @update:model-value="(val) => emit('update:visible', val)" width="600px" :close-on-click-modal="false"
    @close="handleCancel">
    <el-form ref="formRef" :model="formData" :rules="formRules" label-width="100px" class="menu-form">
      <el-divider>菜单配置</el-divider>
      <el-form-item label="菜单标题" prop="title">
        <el-input v-model="formData.title" placeholder="请输入菜单标题" />
      </el-form-item>
      <el-form-item label="上级菜单" prop="parentId">
        <el-tree-select v-model="formData.parentId" :data="menuTree"
          :props="{ label: (data) => data.meta?.title, value: 'id', children: 'children' }" placeholder="请选择上级菜单"
          clearable check-strictly style="width: 100%">
        </el-tree-select>
        <div class="field-tip">一级菜单不选择或清空上级菜单（parentId值为0）</div>
      </el-form-item>
      <el-form-item label="菜单图标" prop="icon">
        <el-input v-model="formData.icon" placeholder="请输入菜单图标" />
      </el-form-item>
      <el-form-item label="菜单排序" prop="rank">
        <el-input-number v-model="formData.rank" :min="0" :max="999" />
      </el-form-item>
      <el-form-item label="菜单状态" prop="status">
        <el-select v-model="formData.status" placeholder="请选择菜单状态">
          <el-option label="启用" :value="0" />
          <el-option label="禁用" :value="1" />
        </el-select>
      </el-form-item>

      <el-divider>路由配置</el-divider>
      <el-form-item label="路由名称" prop="name">
        <el-input v-model="formData.name" placeholder="请输入路由名称" />
      </el-form-item>
      <el-form-item label="路由路径" prop="path">
        <el-input v-model="formData.path" placeholder="请输入路由路径" />
      </el-form-item>

      <!-- 根据菜单级别显示不同字段 -->
      <el-form-item label="组件路径" prop="component">
        <template v-if="isRootMenu">
          <el-input v-model="formData.component" placeholder="Layout" disabled />
          <div class="field-tip">父级菜单固定使用Layout组件</div>
        </template>
        <template v-else>
          <el-input v-model="formData.component" placeholder="请输入组件路径" />
        </template>
      </el-form-item>

      <!-- 按钮权限只对子菜单显示 -->
      <template v-if="!isRootMenu">
        <el-divider>按钮权限配置</el-divider>
        <el-form-item label="按钮权限">
          <el-select v-model="formData.auths" multiple placeholder="请选择按钮权限">
            <el-option label="新增" value="add" />
            <el-option label="编辑" value="edit" />
            <el-option label="删除" value="delete" />
            <el-option label="导入" value="import" />
            <el-option label="导出" value="export" />
          </el-select>
        </el-form-item>
      </template>
    </el-form>
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="handleCancel">取消</el-button>
        <el-button type="primary" :loading="loading" @click="handleSubmit">
          确定
        </el-button>
      </span>
    </template>
  </el-dialog>
</template>

<style scoped>
.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}

.field-tip {
  font-size: 12px;
  color: #909399;
  margin-top: 4px;
}
</style>